"""
特征降维：低方差过滤；相关系数法；PCA
"""
from sklearn.feature_selection import VarianceThreshold
from scipy.stats import pearsonr
from sklearn.decomposition import PCA
import pandas as pd
from sklearn.datasets import load_wine
from sklearn.preprocessing import StandardScaler

def variance_threshold_demo():
    """
    低方差特征过滤：如果某个特征在所有样本都差不多（方差很小），说明这个特征对样本的区分度不大
    :return:
    """
    # data可以是数组、list、DataFrame，也可以是读取的csv、excel文件
    data = pd.DataFrame([[0, 2, 0, 3],
                         [0, 1, 4, 3],
                         [0, 1, 1, 3]])
    # 创建特征选择器
    selector = VarianceThreshold(threshold=0.2)
    # 调用fit_transform，应用选择器
    selected = selector.fit_transform(data)
    # 输出结果
    print(selected)
    print(selector.get_support())    # 返回布尔值，True表示该特征被选中，False表示该特征被过滤掉
    return None


def pearsonr_demo():
    """
    相关系数法：如果两个特征之间的相关性很高，说明这两个特征是重复的，只保留一个
    但是pearsonr方法：1.只能计算两个特征之间的相关性，不能计算多个特征之间的相关性
                     2. 只能计算出结果，不能直接筛选出特征（一般使用PCA）
    :return:
    """
    # 示例数据：学习时间 vs 考试成绩
    study_hours = [2, 3, 5, 7, 9]
    exam_scores = [60, 70, 85, 90, 95]
    # 计算相关系数
    correlation, p_value = pearsonr(study_hours, exam_scores)
    print("相关系数：", correlation.round(2))
    print("p值：", p_value)    # 显著性系数，一般小于0.05，才说明r有意义
    return None


def pca_demo(n_components=0.8):
    """
    PCA：主成分分析
    n_components: 整数，指定降维后的特征数量
                  小数，指定保留的信息比例，例如0.8表示保留80%的信息
    :return:
    """
    # 加载酒类数据集
    wine = load_wine()
    # print(wine.data.shape)    # (178, 13)
    # print(wine.feature_names)
    # print(wine.target_names)   # ['class_0' 'class_1' 'class_2']
    # 标准化
    scaler = StandardScaler()
    data_scaler = scaler.fit_transform(wine.data)
    # PCA降维
    pca = PCA(n_components=n_components)
    data_pca = pca.fit_transform(data_scaler)
    print("降维后的数据形状：\n",data_pca.shape)




if __name__ == '__main__':
    # 低方差特征过滤
    variance_threshold_demo()
    # 相关系数法
    pearsonr_demo()
    # PCA特征降维
    pca_demo(5)  # 降维到5个特征
    pca_demo(0.95)  # 保留95%的信息                    